<template>
	<!-- <view class="ai"  style="width: 750rpx;height: 90vh;overflow: auto;"> -->
	<view class="ai ai-index">
		<!-- 交流部分 -->
		<view class="exchange" 
			  style="width: 750rpx;height: 100%;overflow: auto;">
			<!-- 交流的每一个内容 -->
			<view 
				v-for="item in exchangeList" :key="item.id"
				:class="{'exchange-message': 1===1, 'exchange-message-bot': item.isBot, 'exchange-message-user': !item.isBot}">
				<!-- 头像图标 -->
				<view class="message-icon" v-if="item.isBot">
					<view class="icon">
						<image :src="item.icon"></image>
					</view>
				</view>
				<!-- 消息内容 -->
				<view class="message-context">
					<view class="bot" v-if="item.isBot">
						<view class="question">
							{{ item.question }}
						</view>
						<view class="line" 
							  style="height: 1px;background-color: #aaa;
									 margin: 5px 0;"></view>
						<view class="answer">
							<text v-if="!item.answer">努力回答中...</text>
							<text v-else>{{ item.answer }}</text>
						</view>
					</view>
					<view class="user" v-else>
						<text class="question">
							{{ item.question }}
						</text>
					</view>
					<view class="copy-btn" style="width: 100%;min-width: 70px; height: 20px;position: relative;">
						<view class="copy-body" @click="copyTextToClipboard(item)"
							  style="position: absolute;top: 0;right: 0;
									 width: 50px;height: 20px;background-color: black;
									 color: white;text-align: center;border-radius: 5px;
									 font-size: 14px;font-weight: bold;">
							复制
						</view>
					</view>
				</view>
				<view class="message-icon" v-if="!item.isBot">
					<view class="icon">
						<image :src="item.icon" mode=""></image>
					</view>
				</view>
			</view>
			<view class="bottom-nothing" style="height: 10%;width: 750rpx;"></view>
		</view>
		<!-- 底部输入框 -->
		<view class="ai-bottom flex-row-around white-blur"
			  style="width: 750rpx;height: 50px;
					 position: absolute;bottom: 0;
					 left: 0;">
			<view class="ai-bottom-input"
				  style="width: 550rpx;height: 40px;background-color: rgba(255, 255, 255, 0);">
				<input v-model="question" type="text" placeholder="请输入问题(也可通过下方语音输入)"/>
			</view>
			<view class="ai-bottom-send" @click="send">
				发送
			</view>
		</view>
	</view>
	<!-- <custom-tabbar></custom-tabbar> -->
	
</template>

<script>
	import { BASE_URL } from '../../utils/CommonValues'
	export default {
		data() {
			return {
				url: 'wss://www.metamirror.cn:8085/websocket',
				// url: 'wss://192.168.150.1:8085/websocket', 
				exchangeList: [],
				websocketUUID: '',
				uuid: '',
				token: '',
				code: '',
				baseUrl: '',
				aiShow: false,
				aiIsRunning: false, // ai问答是否正在进行中
				messages: [], // 提问ai接口需要的数据
				question: '',
				socketHeart: '', // websocket的心跳定时器
				heartStatus: 'stop', // 心跳状态 stop: 多次没有响应(5次以上显示) stay: '已发送, 等待响应', ok: '已响应'
				heartTimes: 0, // 在响应了之后发送了几次心跳包没有反应 
				reconnectTimes: 0, //重连次数
			}
		},
		created() {
			// 登录[获取token]
			uni.request({
				method: 'GET',
				url: `${BASE_URL}/captchaImage`,
				dataType: 'json',
				success: res => {
					this.uuid = res.data.uuid
					this.code = res.data.codeStr
					const data = {
						"username": "admin",
						"password": "admin123",
						"uuid": this.uuid,
						"code": this.code
					}
					var str = JSON.stringify(data)
					uni.request({
						method: 'POST',
						url: `${BASE_URL}/login`,
						header: {
							"Content-Type":"application/json;charset=UTF-8"
						},
						data: str,
						dataType: 'json',
						success: res => {
							if(res.data.code == '200') {
								this.token = res.data.token
								// this.initWebSocket();
							} else {
								uni.showToast({
									title: '连接到服务器失败',
									icon: 'error'
								})
							}
						}
					})
				}
			})
		},
		onLoad() {
			this.baseUrl = BASE_URL;
		},
		onShow() {
			console.log("清空消息")
			this.exchangeList = [];
			if(this.heartStatus == 'stop') {
				this.initWebSocket();
			}
		},
		onUnload() {
			clearInterval(this.socketHeart)
		},
		methods: {
			// 复制
			copyTextToClipboard(item) {
				var copyText = '';
				if(item.answer) {
					copyText = item.answer
				} else {
					copyText = item.question
				}
				console.log("复制的内容", copyText)
			  uni.setClipboardData({
			    data: copyText,
			    success: function () {
			      console.log('内容已复制到剪切板');
			      // 可以添加用户友好的提示，例如使用uni.showToast提示复制成功
			      uni.showToast({
			        title: '已复制',
			        icon: 'none',
			        duration: 2000
			      });
			    }
			  });
			},
			// 发送问题
			send() {
				if(this.heartStatus == 'stop') {
					uni.showToast({
						title: '当前连接未建立, 请等待连接',
						icon: 'error'
					})
					return;
				}
				if(this.aiIsRunning) {
					// 正在进行中, 就直接返回, 防止发送多个
					uni.showToast({
						title: "请等待机器人完成回答后再提问 ^_^",
						icon: 'none'
					})
					return;
				}
				if(!this.question) {
					uni.showToast({
						title: "提问的问题不能为空 ^_^",
						icon: 'none'
					})
					return;
				}
				this.aiIsRunning = true; // 设置ai运行状态为true
				const messageUser = {role:"user", content: this.question}
				this.messages = [];
				this.messages.push(messageUser) // 给提交的参数添加内容
				const exchangeUser = {
					id: Math.random(10000) + 1,
					isBot: false,
					icon: 'https://img2.baidu.com/it/u=1114691281,3994296697&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1716310800&t=912db3d7da35eaf7c1c3eecf99ce41b1',
					question: this.question,
					answer: ''
				}
				const exchangeBot = {
					id: Math.random(10000) + 1,
					isBot: true,
					icon: '../../static/icon/fish.png',
					question: this.question,
					answer: ''
				}
				this.exchangeList.push(exchangeUser)
				this.exchangeList.push(exchangeBot) // 给显示在页面的数据添加内容
				this.question = '';
				// 发送请求部分
				uni.request({
					method: 'POST',
					url: `${this.baseUrl}/baidu/ai-request`,
					dataType: 'json',
					header: {
						"Content-Type": "application/json;charset=utf-8",
						"Authorization": this.token
					},
					data: {
						uuid: this.websocketUUID,
						messages: this.messages
					},
					success: res => {
						if(res.data.code === 500) {
							console.log(res);
							this.aiIsRunning = false;
							this.exchangeList[this.exchangeList.length - 1].answer 
								= "求知的人数太多了, 请稍后再试试吧 ~a"
						} else {
							console.log(res.data)
							if(res.data.statusCode === '404') {
								// uni.showToast({
								// 	title: res.data.message,
								// 	icon: 'none'
								// })
								this.exchangeList[this.exchangeList.length - 1].answer
									= '请检查网络状态~'
							}
						}
						this.aiIsRunning = false;
					},
					fail: () => {
						this.aiIsRunning = false;
						this.exchangeList[this.exchangeList.length - 1].answer
							= "请检查网络状态~"
						console.log("请求失败")
					}
				})
			},
			initWebSocket() {
				console.log("初始化")
				wx.connectSocket({  
					url: this.url,
					header: { //请求头
						'content-type': 'application/json',
						'Access-Token': this.token, //携带token认证字段
					},
				    success: (res) => {  
						console.log("连接成功", res)
						this.heartStatus = 'ok'
						// uni.showToast({
						// 	title: 'websocket连接成功'
						// })
						this.socketHeart = setInterval(() => {
							if(this.heartStatus == 'ok') {
								sendMessage(JSON.stringify({
									messageType: '7',
									uuid: this.websocketUUID,
									messageContext: '心跳'
								}))
								// 发送了心跳之后把状态修改为心跳执行中
								this.heartStatus = 'stay';
							} else {
								this.heartTimes = this.heartTimes + 1;
								if(this.heartTimes > 5) {
									console.log("没有响应超过5次", this.socketHeart)
									this.heartStatus = 'stop';
									if(this.reconnectTimes == 0) {
										uni.showToast({
											title: '当前连接不可用, 正在尝试重新连接',
											icon: 'none'
										})
									}
									clearInterval(this.socketHeart);
									this.initWebSocket(); // 重新连接
									this.reconnectTimes = this.reconnectTimes + 1;
								}
							}
						}, 1000)
				    },  
				    fail: (error) => {  
						this.status = 1;
						console.error('WebSocket连接打开失败，请检查！'); 
						this.heartStatus = 'stop';
				    },
					timeout: 10000,
				});  
				  
				// 监听WebSocket连接打开事件  
				wx.onSocketOpen((res) => {
					this.status = 0;
					wx.setStorageSync('isConnected', true) // 把存储中 isConnected 设置为 true
				});  
				
				// 监听 websocket 关闭事件
				wx.onSocketClose(() => {
					this.status = 1;
					wx.setStorageSync('isConnected', false)  // 把存储中 isConnected 设置为 false
					console.log("websocket连接关闭");
				})
				  
				// 监听WebSocket错误  
				wx.onSocketError((res) => {
					this.status = 1;
					console.log('WebSocket连接打开失败，请检查！');  
				});  
				  
				// 发送消息  
				const sendMessage = (msg) => {  
				  if (wx.getStorageSync('isConnected') == true) {  
				    wx.sendSocketMessage({  
				      data: msg  
				    });  
				  } else {  
				    console.log('WebSocket连接未打开，无法发送消息');  
					this.heartStatus = 'stop';
				  }  
				}  
				  
				// 监听WebSocket接受到服务器的消息事件  
				wx.onSocketMessage((res) => { 
					const data = res.data;
					console.log("websocket的响应", data)
					const websocketMessage = JSON.parse(data);
					// 获取到返回的消息类型
					const messageType = websocketMessage['messageType'];
					if(messageType === '1') {
						// 1 表示第一次连接服务器返回一个uuid [保存uuid]
						this.websocketUUID = websocketMessage['uuid']
						console.log(this.websocketUUID)
					}
					if(messageType === '7') {
						// 7 表示是心跳信息
						this.heartStatus = 'ok';
						this.heartTimes = 0;
					}
					if(messageType === '3') {
						// 3 表示服务器返回ai相关的消息, 需要展示到页面
						const messageContext = websocketMessage['messageContext']
						var result = messageContext.result;
						const end = messageContext.end;
						console.log(result)
						// messageContext.sentenceId == 0 表示是第一条数据
						// if(messageContext.sentenceId == 0) {
						// 	// this.result += '回答: \n'
						// 	result += ''
						// }
						
						if(!result && messageContext.sentenceId == 0) {
							// 如果回答的结果为 null, 大概率是后端挂了
							result = "提问的人太多了, 请稍后重试~~~"   
							this.aiIsRunning = false;
							console.log("第一条回答为空")
						}
						this.exchangeList[this.exchangeList.length - 1].answer =
						this.exchangeList[this.exchangeList.length - 1].answer + result
						
						if(end) {
							// 如果当前段落是最后一个段落, 表示回答完成
							this.aiIsRunning = false;
							// 可以在这里给messages添加机器人的回答
							// 格式为 {"role":"assistant","content":"joker"}
							const obj = {
								"role": "assistant",
								"content": this.exchangeList[this.exchangeList.length - 1].answer,
							}
							this.messages.push(obj)
						}
					}
				}); 
			},
		}
	}
</script>

<style lang="less">
.ai {
	position: relative;
	width: 750rpx;
	height: 100vh;
}
input {
	width: 100%;
	height: 100%;
	border-radius: 10px;
	border: 2px solid black;
	line-height: 40px;
	font-size: 16px;
	font-weight: bold;
	// letter-spacing: 10px; 
	padding: 0 10px;
	box-sizing: border-box;
	transition: all .3s;
}
input:focus {
	border: 2px solid skyblue;
}
.ai-bottom-send {
	box-sizing: border-box;
	width: 150rpx;
	height: 40px;
	border-radius: 10px;
	background-color: black;
	color: white;
	font-weight: bold;
	line-height: 40px;
	text-align: center;
	box-shadow: 0 0 10px 0 #aaa;
}

.exchange-message {
	width: 100%;
	display: flex;
	justify-content: start;
	align-items: start;
	margin-top: 10px;
	.message-icon {
		width: 100rpx;
		height: 30px;
		.icon {
			width: 30px;
			height: 30px;
			margin: 0 auto;
			image {
				width: 100%;
				height: 100%;
			}
		}
	}
	.message-context {
		box-sizing: border-box;
		max-width: 500rpx;
		min-height: 20px;
		line-height: 20px;
		border: 3rpx solid #aaa;
		background-color: white;
		padding: 5px 10px;
		border-radius: 10px;
		letter-spacing: 2px;
	}
}
.exchange-message-bot {
	justify-content: flex-start;
}
.exchange-message-user {
	justify-content: flex-end;
}
</style>
